﻿using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using WeChat.Api.Common;
using WeChat.Api.Model.Close;
using WeChat.Api.Model.CreateOrder;
using WeChat.Api.Model.SearchOrder;

namespace WeChat.Api.Controllers
{
    [ApiController]
    [Route("api/[controller]")]
    public class WeChatController : ControllerBase
    {
        public readonly IQRCode _qRCode;
        public WeChatController(IQRCode qRCode)
        {
            _qRCode = qRCode;
        }
        /// <summary>
        /// 统一下单接口
        /// </summary>
        /// <param name="total">支付金额</param>
        /// <param name="OrderId">订单ID</param>
        /// <param name="pixel">像素大小</param>
        [HttpPost("PayOrder")]
        public async Task<ReturnPayOrder> PayOrder(int total, string OrderId)
        {
            var orderNumber = $"{DateTime.Now:yyyyMMddHHmmssff}{CodeHelper.CreateNumCode(3)}";
            HttpClient client = new HttpClient(new HttpHandler());
            var req = new PayOrder
            {
                appid = WeChatConfig.appid,
                mchid = WeChatConfig.mchid,
                description = "nihao",
                out_trade_no = orderNumber,
                notify_url = "http://www.homelist.vip/api/wechat/WxPayCallback",
                amount = new Amount
                {
                    total = total,
                    currency = "CNY"
                }
            };
            var bodyJson = new StringContent(req.ToJson(), Encoding.UTF8, "application/json");
            var resp = await client.PostAsync("https://api.mch.weixin.qq.com/v3/pay/transactions/native", bodyJson);
            // 注意！！！ 这个resp只是http的结果，需要把接口具体返回的值读取出来，如果接口报错的话，这地方可以看到具体的错误信息，我就是在这里入坑的。
            var respStr = await resp.Content.ReadAsStringAsync();

            var respos = respStr.ToObject<ReturnPayOrder>();
            return respos;


        }
        /// <summary>
        /// 动态生成二维码（http://）
        /// </summary>
        /// <param name="url">下载路径</param>
        /// <param name="pixel">像素大小</param>
        [HttpGet("GetQRCode")]

        public void GetQRCode(string url, int pixel)
        {

            Response.ContentType = "image/jpeg";

            var bitmap = _qRCode.GetQRCode(url, pixel);

            MemoryStream ms = new MemoryStream();

            bitmap.Save(ms, ImageFormat.Jpeg);

            Response.Body.WriteAsync(ms.GetBuffer(), 0, Convert.ToInt32(ms.Length));

            Response.Body.Close();

        }
        /// <summary>
        /// 微信支付成功结果回调接口
        /// </summary>
        /// <returns>退款通知http应答码为200且返回状态码为SUCCESS才会当做商户接收成功，否则会重试。注意：重试过多会导致微信支付端积压过多通知而堵塞，影响其他正常通知。</returns>
        [HttpPost("WxPayCallback")]
        public async Task<ReturnNotifyModel> WxPayCallback()
        {

            FileHelper.AddLog("进入", "weixin1");
            FileHelper.AddLog(HttpContext.Request.Path.ToString(), "weixin1");

            try
            {
                using (StreamReader sr = new StreamReader(Request.Body, Encoding.UTF8))
                {

                    string strContent = sr.ReadToEndAsync().Result;
                    FileHelper.AddLog(strContent, "weixin1");
                    var wxPayNotifyModel = strContent.ToObject<WxPayNotifyModel>();
                    var decryptStr = AesGcmHelper.AesGcmDecrypt(wxPayNotifyModel.resource.associated_data, wxPayNotifyModel.resource.nonce, wxPayNotifyModel.resource.ciphertext, "89chulmpeQlk568752345UIcd891512a");
                    return decryptStr.ToString().ToObject<ReturnNotifyModel>();

                }



            }
            catch (Exception e)
            {
                FileHelper.AddLog("读取异常", "weixin1");
                throw;
            }

        }
        /// <summary>
        /// 订单查询    1217752501201407033233368018
        /// </summary>
        /// <param name="OrderSno">订单号</param>
        /// <returns></returns>
        [HttpGet("Search")]
        public async Task<OrderSelect> Search(string OrderSno)
        {
            // 查询订单
            var url = $"https://api.mch.weixin.qq.com/v3/pay/transactions/out-trade-no/" + OrderSno + "?mchid=" + WeChatConfig.mchid;
            var client = new HttpClient(new HttpHandler());
            var resp = await client.GetAsync(url);
            var respStr = await resp.Content.ReadAsStringAsync();
            var payModel = respStr.ToObject<OrderSelect>();
            return payModel;
        }
        /// <summary>
        /// 订单关闭
        /// </summary>
        /// <param name="OrderSno">订单号</param>
        /// <returns></returns>
        [HttpPost("Close")]
        public async Task<CloseOrder> Close(string OrderSno)
        {
            var url = $"https://api.mch.weixin.qq.com/v3/pay/transactions/out-trade-no/" + OrderSno + "/close";
            var client = new HttpClient(new HttpHandler());
            var bodyJson = new StringContent(new { mchid = WeChatConfig.mchid }.ToJson(), Encoding.UTF8, "application/json");
            var resp = await client.PostAsync(url, bodyJson);
            var respStr = await resp.Content.ReadAsStringAsync();
            var closeModel = new CloseOrder();
            if (!string.IsNullOrEmpty(respStr))
                closeModel = respStr.ToObject<CloseOrder>();
            return closeModel;
        }
        [HttpPost("ReturnMoney")]
        public async Task<ReturnAmount> ReturnMoney()
        {
            var mch_id = "1632719416";
            //申请退款
            var req = new ApplyAmount
            {
                out_refund_no = GenerateOutTradeNo(mch_id),//要退回的那个订单号
                out_trade_no = "380164135507199237",//当前退款的订单号。（比如你下单有个订单号，那退款是不是也要有自己的订单号）
                reason = "测试行不行",
                //这个是退款结果通知回调，要看需求，其实退款后微信给消息的
                //我们这里的通知是对系统做记录的。所以要看需不需要。
                notify_url = "http://api.xxxx.com/api/pay/RefundNotifyUrl",
                amount = new RefundsAmountModel
                {
                    refund = 1,
                    total = 500,
                    currency = "CNY"
                }
            };

            var url = $"https://api.mch.weixin.qq.com/v3/refund/domestic/refunds";
            var client = new HttpClient(new HttpHandler());
            var bodyJson = new StringContent(req.ToJson(), Encoding.UTF8, "application/json");

            var resp = await client.PostAsync(url, bodyJson);
            var respStr = await resp.Content.ReadAsStringAsync();
            var payModel = respStr.ToObject<ReturnAmount>();
            return payModel;
        }
        public static string GenerateOutTradeNo(string mchId)
        {
            var ran = new Random();
            return string.Format("{0}{1}{2}", mchId, DateTime.Now.ToString("yyyyMMddHHmmss"), ran.Next(999));
        }
    }
}
